package org.wggds.webservices;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.wggds.webservices.io.WggdsQueryExcpetion;
import org.wggds.webservices.io.WggdsQueryInputUtil;
import org.wggds.webservices.io.WggdsResultException;
import org.wggds.webservices.io.WggdsResultUtilXml;
import org.wggds.webservices.io.data.ErrorId;
import org.wggds.webservices.io.data.QueryResult;
import org.wggds.webservices.io.data.WggdsError;
import org.wggds.webservices.io.query.CompositionSearchQuery;
import org.wggds.webservices.io.query.IdListQuery;
import org.wggds.webservices.io.query.ListOperationQuery;
import org.wggds.webservices.io.query.MassSearchQuery;
import org.wggds.webservices.io.query.SubstructureQuery;

public abstract class AbstractBasicHttpServletExample extends HttpServlet{
	private static final long serialVersionUID=8960997710941386477L;
	
	Pattern subStructureP=Pattern.compile("substructure");
	Pattern compositionP=Pattern.compile("composition");
	Pattern massP=Pattern.compile("mass");
	Pattern listOperationP=Pattern.compile("listOperation");
	Pattern idListP=Pattern.compile("idList");
	
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{
		String requestedURI=req.getPathInfo();
		
		WggdsResultUtilXml xmlWriter=new WggdsResultUtilXml(requestedURI,getNamespace());
		
		String returnXml=null;
		try{
			List<QueryResult> results=null;
			if(subStructureP.matcher(requestedURI).find()){
				SubstructureQuery query=WggdsQueryInputUtil.parseSubstructureQuery(req.getParameter("query"));
				results=runSubStructureQuery(query, req, resp, xmlWriter);
			}else if(compositionP.matcher(requestedURI).find()){
				CompositionSearchQuery query=WggdsQueryInputUtil.parseCompositionSearchQuery(req.getParameter("query"));
				results=runCompositionSearchQuery(query, req, resp, xmlWriter);
			}else if(massP.matcher(requestedURI).find()){
				MassSearchQuery query=WggdsQueryInputUtil.parseMassSearchQuery(req.getParameter("query"));
				results=runMassSearchQuery(query, req, resp, xmlWriter);
			}else if(listOperationP.matcher(requestedURI).find()){
				ListOperationQuery query=WggdsQueryInputUtil.parseListOperationQuery(req.getParameter("query"));
				results=runListOperationQuery(query, req, resp, xmlWriter);
			}else if(idListP.matcher(requestedURI).find()){
				IdListQuery query=WggdsQueryInputUtil.parseIdListQuery(req.getParameter("query"));
				results=runIdListQuery(query, req, resp, xmlWriter);
			}
			
			if(results!=null && results.size()>0){
				String randomId=WggdsResultUtilXml.generateRandomId();

				returnXml=xmlWriter.createResult(results, randomId, true, getGlydeVersion());
			}
		}catch(WggdsQueryExcpetion e){
			try{
				xmlWriter.addError(new WggdsError(ErrorId.UnknownError));
				returnXml=xmlWriter.finishRecordResult();
			}catch(WggdsResultException e1){
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}catch(WggdsResultException e){
			try{
				xmlWriter.addError(new WggdsError(ErrorId.UnknownId));
				returnXml=xmlWriter.finishRecordResult();
			}catch(WggdsResultException e1){
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
		if(xmlWriter.isFinished()==false){
			if(xmlWriter.isStreaming()==false){
				try{
					xmlWriter.startRecordResult("0");
				}catch(WggdsResultException e){
					resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Opps something has gone wrong");
					e.printStackTrace();
					return;
				}
			}
			
			try{
				returnXml=xmlWriter.finishRecordResult();
			}catch(WggdsResultException e){
				resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Opps something has gone wrong");
				e.printStackTrace();
				return;
			}
		}
		
		BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(resp.getOutputStream()));
		writer.write(returnXml);
		writer.flush();
	}
	
	public abstract List<QueryResult> runSubStructureQuery(SubstructureQuery query, HttpServletRequest req, HttpServletResponse resp, WggdsResultUtilXml xmlWriter) throws WggdsResultException;
	
	public abstract List<QueryResult> runCompositionSearchQuery(CompositionSearchQuery query, HttpServletRequest req, HttpServletResponse resp, WggdsResultUtilXml xmlWriter);
	
	public abstract List<QueryResult> runMassSearchQuery(MassSearchQuery query, HttpServletRequest req, HttpServletResponse resp, WggdsResultUtilXml xmlWriter);
	
	public abstract List<QueryResult> runListOperationQuery(ListOperationQuery query, HttpServletRequest req, HttpServletResponse resp, WggdsResultUtilXml xmlWriter);
	
	public abstract List<QueryResult> runIdListQuery(IdListQuery query, HttpServletRequest req, HttpServletResponse resp, WggdsResultUtilXml xmlWriter);
	
	public abstract String getNamespace();
	
	public abstract String getGlydeVersion();
}
